package com.black.pay.controller;

import com.alibaba.fastjson.JSONObject;
import com.black.pay.cache.SessionCache;
import com.black.pay.cache.UserTokenCache;
import com.black.pay.model.MessageUser;
import com.black.pay.model.User;
import com.black.pay.model.UserExample;
import com.black.pay.service.UserMessageService;
import com.black.pay.service.UserService;
import com.black.pay.utils.PasswordUtils;
import com.black.pay.utils.TokenUtil;
import com.black.pay.vo.R;
import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException;
import com.sun.deploy.net.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api/user")
@CrossOrigin
public class UserController extends BaseController{
    @Autowired
    UserService userService;
    @Autowired
    UserMessageService userMessageService;
    @Autowired
    UserTokenCache userTokenCache;
    @Autowired
    SessionCache sessionCache;

    @PostMapping("/login")
    public R login(HttpServletResponse response, @RequestParam("username") String username, @RequestParam("password") String password){
        User user = getUser(username);
        if (user == null) {
            return R.fail("用户不存在");
        }
        if (PasswordUtils.encrypt(username, password).equals(user.getPassword())) {
            String token = TokenUtil.generate();
            Cookie cookie = new Cookie("token", token);
            cookie.setPath("/");
            response.addCookie(cookie);
            userTokenCache.put(token,username);
            return R.ok().put("token",token);
        }else{
            return R.fail();
        }
    }

    private User getUser(String username) {
        if (StringUtils.isEmpty(username)) {
            return null;
        }
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(username);
        return userService.selectOne(userExample);
    }

    @PostMapping("/register")
    public R save(@Validated User user, BindingResult result) {
        R r = validateParams(result);
        if (r != null) {
            return r;
        }
        user.setPassword(PasswordUtils.encrypt(user.getUsername(),user.getPassword()));
        user.setGmt(new Date());
        try {
            userService.save(user);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                return R.fail();
            }
            e.printStackTrace();
        }
        return R.ok();
    }

    @GetMapping("/get/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().put("user", userService.get(id));
    }

    @GetMapping("/get/me")
    public R get(@RequestParam("token")String token) {
        User user = getUser(userTokenCache.getUsername(token));
        if (user == null) {
            return R.error401();
        }else {
            if (user == null) {
                return R.error401();
            }
            return R.ok().put("user", user);
        }
    }

    @PostMapping("send")
    public R send(@RequestParam("token") String token, @RequestParam("msg") String message, @RequestParam("to") Long reviceUserId) throws IOException {
        MessageUser messageUser = new MessageUser();
        messageUser.setGmt(new Date());
        User user = getUser(userTokenCache.getUsername(token));
        if (user == null) {
            return R.error401();
        }
        User toUser = userService.get(reviceUserId);
        if (toUser == null) {
            return R.fail("no such user");
        }
        messageUser.setUserId(user.getId());
        messageUser.setRevUserId(reviceUserId);
        messageUser.setStatus(0);
        userMessageService.save(messageUser);
        JSONObject msg = new JSONObject();
        msg.put("type","newMsg");
        msg.put("to", reviceUserId);
        msg.put("msg", message);
        String toTOken = userTokenCache.getToken(toUser.getUsername());
        if (toTOken != null) {
            sessionCache.sendMessage(toTOken,msg);
            sessionCache.sendMessage(token,msg);
        }else {
            msg.put("tips", toUser.getUsername() + " is not online ");
            sessionCache.sendMessage(token,msg);
        }
        return R.ok();
    }

    private Long getUserId(HttpServletRequest request) {
        HttpSession session = request.getSession();
        Object userId  = session.getAttribute("userId");
        if (userId != null) {
            return (Long) userId;
        }else {
            return null;
        }
    }

    @GetMapping("/list/all")
    public R listAll(){
        return R.ok().put("users", userService.list(new UserExample()));
    }
}
